package com.xbongbong.saas.help.workflow;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.product.pojo.ProductSavePojo;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductionOrderProductEntity;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.help.SaasProductHelp;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.ProductionOrderProductModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 *
 * @author 魏荣杰
 *
 */
@Component
public class ProductionOrderHelp {

    @Resource
    private EsHelper esHelper;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private SaasProductHelp saasProductHelp;
    @Resource
    private ProductionOrderProductModel productionOrderProductModel;


    public boolean judgeProductionOrderAllInBound(Long instockId, Long productionOrderId, String corpid, List<ProductSavePojo> productSavePojoList) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID), productionOrderId.toString()));
        boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE), String.valueOf(OutstockTypeEnum.MATERIEL_OUTSTOCK.getCode())));
        boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.SAAS_LINK_BUSINESS_ID);
        List<PaasFormDataEntityExt> outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
        List<Long> outstockIdIn = new ArrayList<>();
        outstockList.forEach(outstock -> outstockIdIn.add(outstock.getId()));
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("outWarehouseIdIn", outstockIdIn);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        // 拿到出库单的所有产品
        List<OutstockProductEntity> outstockProductEntityList= outstockProductModel.findEntitys(param);
//        Map<Long,Double> productionOrderProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        Map<Long,Double> lineMatchPurchaseProductNum = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        Map<Long,OutstockProductEntity> outstockProductMap = new HashMap<>(outstockProductEntityList.size());

        boolean needMerge = false;
        for (ProductSavePojo productSavePojo : productSavePojoList){
            if (Objects.isNull(productSavePojo.getRefProductId())) {
                needMerge = true;
                break;
            }
        }
        Map<Long,Double> instockNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!needMerge) {
            for (ProductSavePojo productSavePojo : productSavePojoList){
                Double num = instockNumMap.getOrDefault(productSavePojo.getRefProductId(),0D);
                num = Arith.add(num,productSavePojo.getNum());
                instockNumMap.put(productSavePojo.getRefProductId(), num);
            }
            boolean isAllOutBound = true;
            List<OutstockProductEntity> updateList = new ArrayList<>();
            for (OutstockProductEntity entity : outstockProductEntityList) {
                Long key = entity.getId();
                if (instockNumMap.containsKey(key)) {
                    //剩余未入
                    Double unStockNum = Arith.sub(entity.getProductNum(),entity.getInstockNum());
                    //当前入库
                    Double amendNum = instockNumMap.get(entity.getId());
                    Double instockNum = Arith.sub(unStockNum,amendNum) < 0 ? unStockNum : amendNum;
                    entity.setInstockNum(Arith.add(instockNum, entity.getInstockNum()));
                    // 只要有一个入库数量 < 产品总数，就应该是未全部入库
                    if (Arith.sub(entity.getProductNum(),entity.getInstockNum())  > 0) {
                        isAllOutBound = false;
                    }
                    updateList.add(entity);
                } else {
                    //该物料出库产品不在入库单中，生产单肯定没退完
                    if (Arith.sub(entity.getProductNum(),entity.getInstockNum()) > 0) {
                        isAllOutBound = false;
                    }
                }
            }
            if (!updateList.isEmpty()) {
                outstockProductModel.updateBatch(updateList, corpid);
            }
            return isAllOutBound;
        }else {
            for (OutstockProductEntity entity : outstockProductEntityList) {
                Double num = instockNumMap.getOrDefault(entity.getProductId(),0D);
                num = Arith.add(num, entity.getProductNum());
                instockNumMap.put(entity.getProductId(),num);
            }
            return saasProductHelp.judgeAllInBound(instockNumMap, productionOrderId, InstockTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(),corpid,productSavePojoList,instockId);
        }


//        for (OutstockProductEntity entity : outstockProductEntityList){
//            Double num = productionOrderProductMap.getOrDefault(entity.getProductId(),0D);
//            num += entity.getProductNum();
//            productionOrderProductMap.put(entity.getProductId(),num);
//            lineMatchPurchaseProductNum.put(entity.getId(), entity.getProductNum());
//            outstockProductMap.put(entity.getId(), entity);
//        }
//        // 更新物料出库已退货数量
//        productSavePojoList.forEach(item -> {
//            Long refProductId = item.getRefProductId();
//            if (Objects.nonNull(refProductId) && outstockProductMap.containsKey(refProductId)) {
//                OutstockProductEntity outstockProductEntity = outstockProductMap.get(refProductId);
//                outstockProductEntity.setInstockNum(Arith.add(outstockProductEntity.getInstockNum() == null ? 0 : outstockProductEntity.getInstockNum(), item.getNum()));
//                updateList.add(outstockProductEntity);
//            }
//        });
//        if (!updateList.isEmpty()) {
//            outstockProductModel.updateBatch(updateList, corpid);
//        }
    }


    public boolean judgeProductionOrderAllOutBound(Long outstockId, Long productionOrderId, String corpid, List<ProductSavePojo> productSavePojoList) throws XbbException {
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("productionOrderId", productionOrderId);
        param.put("del", 0);
        param.put("type",2);
        // 拿到合同的所有物料产品
        List<ProductionOrderProductEntity> productionOrderProductEntityList = productionOrderProductModel.findEntitys(param);
        Map<Long,Double> productionOrderOutstockNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductSavePojo entity : productSavePojoList) {
            if (Objects.nonNull(entity.getRefProductId())) {
                Double num = productionOrderOutstockNumMap.getOrDefault(entity.getRefProductId(), 0D);
                num = Arith.add(entity.getNum(), num);
                productionOrderOutstockNumMap.put(entity.getRefProductId(), num);
            }
        }
        List<ProductionOrderProductEntity> updateList = new ArrayList<>();
        boolean isAllOutBound = true;

        for (ProductionOrderProductEntity entity : productionOrderProductEntityList){
            if (productionOrderOutstockNumMap.containsKey(entity.getId())) {
                Double workOrderOutstockNum = Objects.isNull(entity.getOutstockNum()) ? 0D : entity.getOutstockNum();
                if (Arith.sub(entity.getProductNum() , Arith.add(workOrderOutstockNum, productionOrderOutstockNumMap.getOrDefault(entity.getId(), 0D))) > 0) {
                    isAllOutBound = false;
                }
                entity.setOutstockNum(productionOrderOutstockNumMap.getOrDefault(entity.getId(), 0D));
                entity.setUpdateTime(DateTimeUtil.getInt());
                updateList.add(entity);
            }else{
                //该产品不在出库单中，生产单肯定没出完
                if (Arith.sub(entity.getProductNum(), entity.getOutstockNum()) > 0) {
                    isAllOutBound = false;
                }
            }
        }
        if (!updateList.isEmpty()) {
            productionOrderProductModel.updateOutstockBatch(updateList,corpid);
        }
        return isAllOutBound;
//        return saasProductHelp.judgeAllOutBound(productionOrderProductMap,productionOrderId,OutstockTypeEnum.MATERIEL_OUTSTOCK.getCode(),corpid,productSavePojoList, outstockId);
    }


}
